public class AccountAddressTriggerHandler{

static Set<Id> accaddressupdateid=new Set<Id>();
static Set<Id> accaddressinsertid=new Set<Id>();

public void AccountAddressInsert(List<Account_Address__c> accaddresslist){
     Set<Id> addressid=new Set<Id>();
     Set<Id> accid=new Set<Id>();
    List<Account_Address__c> oldaccountaddresslist=new List<Account_Address__c>();
    List<Account_Address__c> oldaccountaddressupdatelist=new List<Account_Address__c>();
    Account_Address__c add=new Account_Address__c();
    
    
    if(accaddresslist!=null&&accaddresslist.size()>0){ 
        add=accaddresslist[0];
        for(Account_Address__c accaddress: accaddresslist){
            addressid.add(accaddress.Id);
            accid.add(accaddress.Account__c);
        }       
        oldaccountaddresslist=[select Account__c,Preferred__c from Account_Address__c where Preferred__c=true AND Account__c IN:accid AND Id NOT IN:addressid];
        
    for(Account_Address__c accaddress: accaddresslist){
            
            // To insert country code..
                if(accaddress.Country__c!=null){
                String country=accaddress.Country__c;
                String c1=country.substring((country.indexOf('(')+1),country.indexOf(')'));
                accaddress.Country_Name__c=c1;
                }
            // To insert state code..
                if(accaddress.State__c!=null){
                    String state=accaddress.State__c;
                    String c1=state.substring((state.indexOf('(')+1),state.indexOf(')'));
                    accaddress.State_Name__c=c1;
                }
            system.debug('&&oldaccountaddresslist'+ oldaccountaddresslist);
            system.debug('&&accaddresslist'+ accaddresslist);
            if(oldaccountaddresslist!=null && oldaccountaddresslist.size()>0){                 
                      
                   if(accaddress.Preferred__c==true) {      
                    for(Account_Address__c oldaddress : oldaccountaddresslist){
                             oldaddress.Preferred__c=false;
                             oldaccountaddressupdatelist.add(oldaddress);
                             accaddressinsertid.add(oldaddress.Id);       
                    }
                  }
                    
            }else{
                add.Preferred__c=true;
            }                             
        }
        
        system.debug('&&oldaccountaddressupdatelist'+ oldaccountaddressupdatelist);
      if(!oldaccountaddressupdatelist.IsEmpty()){
          update oldaccountaddressupdatelist;
      }
    
    }
    
 }
public void AccountAddressUpdate(List<Account_Address__c> newaccaddresslist,List<Account_Address__c> oldaccaddresslist){
     Set<Id> addressid=new Set<Id>();
     Set<Id> accid=new Set<Id>();
    List<Account_Address__c> oldaccountaddresslist=new List<Account_Address__c>();
    List<Account_Address__c> oldaccountaddressupdatelist=new List<Account_Address__c>();
    
    if(newaccaddresslist!=null&&newaccaddresslist.size()>0){    
        for(Account_Address__c accaddress: newaccaddresslist){
            addressid.add(accaddress.Id);
            accid.add(accaddress.Account__c);
        }       
        oldaccountaddresslist=[select Account__c,Preferred__c from Account_Address__c where Preferred__c=true AND Account__c IN:accid AND Id NOT IN:addressid];
        
        
            for(Account_Address__c newaccaddress: newaccaddresslist){
            	// To insert country code..
                if(newaccaddress.Country__c!=null){
                String country=newaccaddress.Country__c;
                String c1=country.substring((country.indexOf('(')+1),country.indexOf(')'));
                newaccaddress.Country_Name__c=c1;
                }
                // To insert state code..
                if(newaccaddress.State__c!=null){
                    String state=newaccaddress.State__c;
                    String c1=state.substring((state.indexOf('(')+1),state.indexOf(')'));
                    newaccaddress.State_Name__c=c1;
                }
                for(Account_Address__c oldaccaddress: oldaccaddresslist){
                    if((newaccaddress.Preferred__c==true && oldaccaddress.Preferred__c==false && newaccaddress.Account__c==oldaccaddress.Account__c)){ 
                        for(Account_Address__c accvalue: oldaccountaddresslist){
                              accvalue.Preferred__c=false;        
                              oldaccountaddressupdatelist.add(accvalue);
                              accaddressupdateid.add(accvalue.Id);                            
                          } 
                    } else{
                    for(Account_Address__c accval: newaccaddresslist){
                          
                            if(accaddressupdateid.contains(accval.id) ){
                            }else{
                            if(accaddressinsertid.IsEmpty()&&(newaccaddress.Preferred__c==false && oldaccaddress.Preferred__c==true))
                             trigger.new[0].addError('cannot update');  
                            }
        }
                    
                    }
                
                }
            }
        }
        
        if(!oldaccountaddressupdatelist.isEmpty()){
                try{
                    
                    update oldaccountaddressupdatelist;
                }catch(Exception e){
                    system.debug('# Exception while updating : '+e);
                }
            }                                  
    }
    public void AccountAddressDelete(List<Account_Address__c> accountaddresslist){
        if(accountaddresslist!=null&&accountaddresslist.size()>0){
            system.debug('@@accountemaillist '+accountaddresslist);
            for(Account_Address__c accaddress: accountaddresslist){
            
            if(accaddress.Preferred__c==true){
                    trigger.old[0].addError('Cannot delete prefered record');  
                }
            }
        
        }

    }
/************************************************************************
        Purpose     : Test Class                  
        Parameters  : None
        Returns     : None
***********************************************************************/
    @isTest(SeeAllData=false)
     static public void testAccountEmailTriggerHandler() {
         PIMS_Reserved_Id__c pimsid=new PIMS_Reserved_Id__c();
         pimsid.PIMS_Id__c='0000-0000';
         pimsid.Used__c=false;
         insert pimsid;
         
         Account acc=new Account();
         acc.Name='test';
         acc.Type='SSO';
         insert acc;
         
         Account_Address__c accaddress=new Account_Address__c();
         accaddress.Account__c=acc.Id;
         accaddress.Address_Type__c='Home';
         accaddress.Country__c='Canada (CA)';
         accaddress.State__c='Test (TT)';
         accaddress.Preferred__c=true;
         insert accaddress;         
         update accaddress;
        
         Account_Address__c accaddress0=new Account_Address__c();
         accaddress0.Account__c=acc.Id;
         accaddress0.Address_Type__c='Home';
         accaddress0.Country__c='Canada (CA)';
         accaddress0.State__c='Test (TT)';
         accaddress0.Preferred__c=true;
         insert accaddress0;    
         
         Account_Address__c accaddress1=new Account_Address__c();
         accaddress1.Account__c=acc.Id;
         accaddress1.Address_Type__c='Home';
         accaddress1.Country__c='Canada (CA)';
         accaddress1.State__c='Test (TT)';
         accaddress1.Preferred__c=false;
         insert accaddress1;    
         accaddress1.Preferred__c=true;     
         update accaddress1;
         
         Account_Address__c accaddress2=new Account_Address__c();
         accaddress2.Account__c=acc.Id;
         accaddress2.Address_Type__c='Home';
         accaddress2.Country__c='Canada (CA)';
         accaddress2.State__c='Test (TT)';
         accaddress2.Preferred__c=false;
         insert accaddress2;    
         delete accaddress2;
         
         
         
     
     }   
}